#pragma once

#include "HashTable.h"

namespace ltw
{
    template<class K,class Hash = HashFunc<K>>
    class unordered_set
    {
        struct SetKeyOfT
        {
            const K& operator()(const K& key)
            {
                return key;
            }
        };
    public:
        typedef typename HashTable<K,const K,SetKeyOfT,Hash>::Iterator iterator;
        typedef typename HashTable<K,const K,SetKeyOfT,Hash>::Const_Iterator const_iterator;

        iterator begin()
        {
            return _ht.Begin();
        }

        iterator end()
        {
            return _ht.End();
        }

        const_iterator begin()const
        {
            return _ht.Begin();
        }

        const_iterator end()const
        {
            return _ht.End();
        }

        pair<iterator,bool> insert(const K& key)
        {
            return _ht.Insert(key);
        }

        iterator Find(const K& key)
        {
            return _ht.Find(key);
        }
        bool Erase(const K& key)
        {
            return _ht.Erase(key);
        }
    public:
        HashTable<K,const K,SetKeyOfT,Hash> _ht;
    };

        
    void Print(const unordered_set<int>& s)
    {
        unordered_set<int>::const_iterator it = s.begin();
        while(it != s.end())
        {
            cout << *it << " ";
            ++it;
        }
        cout << endl;
    }
    void test_set()
    {
        unordered_set<int> s;
        int a[] = {4,2,6,1,3,5,15,7,16,14};
        for(auto e:a)
        {
            s.insert(e);
        }
        for(auto e:s)
        {
            cout << e << " ";
        }
        cout << endl;
        unordered_set<int>::iterator it = s.begin();
        while(it != s.end())
        {
            // *it += 10;
            cout << *it << " ";
            ++it;
        }
        cout << endl;
        // Print(s);
    }

    struct Date
    {
        int _year;
        int _month;
        int _day;
        bool operator==(const Date& d)const
        {
            return _year == d._year && 
                   _month == d._month && 
                   _day == d._day;
        }
    };

    struct HashDate
    {
        size_t operator()(const Date& key)
        {
            return (key._year * 31 + key._month) * 31 + key._day;
        }
    };

    void test_set_1()
    {
        unordered_set<Date,HashDate> us;
        us.insert({2024,7,25});
    }
}